<template>
	<div class="home">
		<el-card class="box-card">
			<div class="desensitized-operating">
				<div class="title">可选操作</div>
				<el-button type="primary" @click="select_file">选择文件</el-button>
				<el-button type="primary" :disabled="read_excel_type" @click="read_excel">{{ desensitization_btn_title }}</el-button>
				<el-button type="primary" :disabled="save_file_as_type" @click="save_file_as">另存文件</el-button>
				<el-button type="primary" :disabled="reset_state" @click="reset_configuration">重置</el-button>
			</div>
			<el-divider></el-divider>
			<div class="set-desensitized-format">
				<div class="title">脱敏格式</div>
				<div class="desensitization-rule">
					<el-input-number v-model="number_prefix_digits" :min="1" :max="9" label="脱敏前缀位数" @change="handleFormatChange"></el-input-number>
					<el-input v-model="desensitized_characters" placeholder="脱敏字符" @change="handleFormatChange"></el-input>
					<el-input-number v-model="number_suffix_digits" :min="1" :max="9" label="脱敏后缀位数" @change="handleFormatChange"></el-input-number>
				</div>
				<div class="tips">提示：前{{ number_prefix_digits }}位{{ desensitized_characters }}后{{ number_suffix_digits }}位</div>
			</div>
		</el-card>
		<el-divider>脱敏数据预览</el-divider>
		<el-tabs v-if="is_the_data_empty == false" v-model="activeName" type="border-card" tab-position="bottom" class="desensitized-data-tabs">
			<el-tab-pane
				v-for="(sheet_id_numbers, index) in sheets_id_numbers"
				:key="index"
				:label="sheet_id_numbers.sheet_name"
				:name="sheet_id_numbers.sheet_name"
			>
				<el-table v-loading="loading" :data="sheet_id_numbers.show_data" stripe border height="440" style="width: 100%">
					<el-table-column prop="id" label="身份证号" />
					<el-table-column prop="row" label="行号" width="120" />
					<el-table-column prop="col" label="列号" width="120" />
					<el-table-column prop="des" label="脱敏" />
				</el-table>
				<div class="pagination">
					<el-pagination
						layout="prev, pager, next, sizes, total"
						:total="sheet_id_numbers.total"
						:pager-count="10"
						:page-sizes="[10, 20, 50, 100]"
						:page-size="sheet_id_numbers.page_size"
						@size-change="handleSizeChange($event, sheet_id_numbers.sheet_name)"
						@current-change="current_change($event, sheet_id_numbers.sheet_name)"
					></el-pagination>
				</div>
			</el-tab-pane>
		</el-tabs>

		<div v-if="is_the_data_empty" v-loading="loading" class="empty-data">
			<el-empty description="数据为空" />
		</div>

		<div class="toolbar">
			<div class="content">
				<transition name="el-fade-in">
					<div v-show="show_saying" class="saying">{{ saying }}</div>
				</transition>
				<div class="prompt">此版本仅支持xlsx文件（v1.0）</div>
			</div>
		</div>
	</div>
</template>

<script setup lang="ts">
import { onMounted, ref } from 'vue';
import { open, save } from '@tauri-apps/api/dialog';
import { invoke } from '@tauri-apps/api/tauri';
import { ElNotification } from 'element-plus';
import { generateRandomQuote } from '@/composables/famousQuotes.ts';

const file_path = ref('');
const activeName = ref('');
const number_prefix_digits = ref(5);
const number_suffix_digits = ref(5);
const desensitized_characters = ref('********');
const saying = ref<string>('人总要抱紧什么才知道自己真的存在，哪怕那只是幻影。');

const sheets_id_numbers = ref<IdNumberTable[]>([]);

const read_excel_type = ref<boolean>(true);
const save_file_as_type = ref<boolean>(true);
const reset_state = ref<boolean>(true);

const loading = ref<boolean>(false);

const is_the_data_empty = ref<boolean>(true);
const show_saying = ref<boolean>(true);

const desensitization_btn_title = ref<string>('开始脱敏');

interface IdNumberTable {
	sheet_name: string;
	id_numbers: IdNumber[];
	total: number;
	page_size: number;
	show_data: IdNumber[];
}

interface IdNumber {
	id: string;
	col: number;
	row: number;
	des: string;
}

function select_file() {
	open({
		title: '选择文件',
		filters: [{ name: 'EXCEL', extensions: ['xlsx'] }],
	}).then((result) => {
		if (result) {
			// 获取选定文件的物理路径
			file_path.value = result as string;
			invoke('update_excel_path', { excelPath: result });
			ElNotification({
				title: '成功选择文件',
				message: file_path.value,
				position: 'bottom-right',
			});
			read_excel_type.value = false;
			reset_state.value = false;
		}
	});
}

function read_excel() {
	loading.value = true;
	invoke('read_excel')
		.then((result) => {
			sheets_id_numbers.value = result as IdNumberTable[];
			if (sheets_id_numbers.value.length > 0) {
				let page_size = 10;
				activeName.value = sheets_id_numbers.value[0].sheet_name;
				for (let i = 0; i < sheets_id_numbers.value.length; i++) {
					let id_numbers = sheets_id_numbers.value[i].id_numbers;
					desensitization(id_numbers);
					sheets_id_numbers.value[i].page_size = page_size;
					sheets_id_numbers.value[i].total = id_numbers.length;
					sheets_id_numbers.value[i].show_data = id_numbers.slice(0, page_size);
				}
				ElNotification({
					message: '脱敏成功',
					type: 'success',
					position: 'bottom-right',
				});
				is_the_data_empty.value = false;
			} else {
				ElNotification({
					message: '没有找到需要脱敏的身份账号',
					type: 'warning',
					position: 'bottom-right',
				});
			}
			desensitization_btn_title.value = '开始脱敏';
			save_file_as_type.value = false;
			read_excel_type.value = true;
			reset_state.value = true;
		})
		.finally(() => {
			loading.value = false;
		});
}

const handleFormatChange = () => {
	if (sheets_id_numbers.value.length > 0) {
		desensitization_btn_title.value = '重新脱敏';
		read_excel_type.value = false;
		ElNotification({
			message: '修改了脱敏规则，需要重新脱敏',
			type: 'warning',
			position: 'bottom-right',
		});
	}
	reset_state.value = false;
};

function current_change(currentPage: number, sheet_name: string) {
	for (let i = 0; i < sheets_id_numbers.value.length; i++) {
		let sheet_id_numbers = sheets_id_numbers.value[i];
		if (sheet_id_numbers.sheet_name === sheet_name) {
			let page_size = sheet_id_numbers.page_size;
			sheet_id_numbers.show_data = sheet_id_numbers.id_numbers.slice((currentPage - 1) * page_size, currentPage * page_size);
		}
	}
}
function handleSizeChange(size: number, sheet_name: string) {
	for (let i = 0; i < sheets_id_numbers.value.length; i++) {
		let sheet_id_numbers = sheets_id_numbers.value[i];
		if (sheet_id_numbers.sheet_name === sheet_name) {
			sheet_id_numbers.page_size = size;
			sheet_id_numbers.show_data = sheet_id_numbers.id_numbers.slice(0, size);
		}
	}
}

function desensitization(id_number: IdNumber[]) {
	// 身份证号脱敏, 350322196403146000 to 350322********6000
	for (let i = 0; i < id_number.length; i++) {
		id_number[i].des =
			id_number[i].id.slice(0, number_prefix_digits.value) + desensitized_characters.value + id_number[i].id.slice(0 - number_suffix_digits.value);
	}
}

const save_file_as = () => {
	save({
		title: '另存文件',
		filters: [{ name: 'EXCEL', extensions: ['xlsx'] }],
	}).then((result) => {
		invoke('save_excel', {
			path: result as string,
			sheetIdNumbers: sheets_id_numbers.value,
			prefix: number_prefix_digits.value,
			suffix: number_suffix_digits.value,
			symbol: desensitized_characters.value,
		})
			.then(() => {
				ElNotification({
					title: '保存文件成功',
					message: result as string,
					type: 'success',
					position: 'bottom-right',
				});
			})
			.catch((error) => {
				if ('invalid args `path` for command `save_excel`: invalid type: null, expected a borrowed string' == error) {
					ElNotification({
						message: '取消保存',
						type: 'warning',
						position: 'bottom-right',
					});
				} else {
					ElNotification({
						message: '保存文件失败',
						type: 'error',
						position: 'bottom-right',
					});
				}
			})
			.finally(() => {
				reset_state.value = false;
			});
	});
};

function reset_configuration() {
	file_path.value = '';
	activeName.value = '';
	number_prefix_digits.value = 5;
	number_suffix_digits.value = 5;
	desensitized_characters.value = '********';
	read_excel_type.value = true;
	save_file_as_type.value = true;
	sheets_id_numbers.value = [];
	is_the_data_empty.value = true;
	desensitization_btn_title.value = '开始脱敏';
	reset_state.value = true;
	ElNotification({
		message: '已经重置',
		type: 'success',
		position: 'bottom-right',
	});
}

onMounted(() => {
	invoke('get_excel_path').then((result) => {
		file_path.value = result as string;
	});
	setInterval(() => {
		show_saying.value = false;
		setTimeout(() => {
			saying.value = generateRandomQuote();
			show_saying.value = true;
		}, 800);
	}, 6000);
});
</script>

<style lang="less">
.home {
	height: 100%;
	width: 100%;
	padding: 20px;
	box-sizing: border-box;
}

.set-desensitized-format > .title {
	font-size: 16px;
	font-weight: 600;
	margin-bottom: 10px;
	display: inline-block;
}

.set-desensitized-format > .title::after {
	content: ':';
	display: inline-block;
	margin: 0 5px;
}

.set-desensitized-format > .tips {
	display: inline-block;
	color: #848484;
	font-size: 12px;
	margin-left: 10px;
}

.desensitization-rule {
	display: inline-block;
}

.desensitization-rule > .el-input-number,
.desensitization-rule > .el-input {
	width: 100px;
	margin: 5px;
}
.desensitization-rule > .el-input {
	width: 200px;
}

.desensitized-operating {
	margin: 10px 0;
	text-align: left;
}
.desensitized-operating > .title {
	display: inline-block;
	font-size: 16px;
	font-weight: 600;
}

.desensitized-operating > .title::after {
	content: ':';
	display: inline-block;
	margin: 0 5px;
}

.desensitized-data-tabs > .el-tabs__content {
	padding: 30px 30px 0 30px;
	font-size: 32px;
	font-weight: 600;
}
.desensitized-data-tabs .pagination {
	margin: 15px auto 5px auto;
	text-align: center;
	display: table;
}
.toolbar {
	height: 20px;
	position: fixed;
	bottom: 5px;
	left: 20px;
	right: 10px;
}
.toolbar > .content {
	width: 100%;
	height: 100%;
	position: relative;
	box-sizing: border-box;
	padding-right: 180px;
}
.toolbar .saying {
	display: block;
	font-size: 12px;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
	width: 100%;
}

.toolbar .prompt {
	display: inline-block;
	font-size: 12px;
	position: absolute;
	right: 0;
	bottom: 5px;
	color: #848484;
}
.empty-data {
	height: 520px;
}
.empty-data > .el-empty {
	height: 100%;
}
</style>
